{
 "cells": [
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "### 简介\n",
    "\n",
    "先看一个例子，某银行是否给用户放贷的判断规则集如下：  \n",
    "\n",
    "```python\n",
    "if 年龄==青年:\n",
    "    if 有工作==是:\n",
    "        if 信贷情况==非常好:\n",
    "            放\n",
    "        else:\n",
    "            不放\n",
    "    else:\n",
    "        if 有自己的房子==是:\n",
    "            if 信贷情况==一般:\n",
    "                不放\n",
    "            else:\n",
    "                放\n",
    "        else:\n",
    "            if 信贷情况==非常好 or 信贷情况==好:\n",
    "                放\n",
    "            else:\n",
    "                if 有工作==是:\n",
    "                    放\n",
    "                else:\n",
    "                    不放\n",
    "elif 年龄==中年:\n",
    "    if 有自己的房子==是:\n",
    "        放\n",
    "    else:\n",
    "        if 信贷情况==非常好 or 信贷情况==好:\n",
    "            放\n",
    "        else:\n",
    "            if 有工作==是:\n",
    "                放\n",
    "            else:\n",
    "                不放\n",
    "elif 年龄==老年:\n",
    "    if 有自己的房子==是:\n",
    "        if 信贷情况==非常好 or 信贷情况==好:\n",
    "            放\n",
    "        else:\n",
    "            不放\n",
    "    else:\n",
    "        if 信贷情况==非常好 or 信贷情况==好:\n",
    "            if 有工作==是:\n",
    "                放\n",
    "            else:\n",
    "                不放\n",
    "        else:\n",
    "            不放\n",
    "if 有自己的房子==是:\n",
    "    放\n",
    "else:\n",
    "    if 有工作==是:\n",
    "        放\n",
    "    else:\n",
    "        不放\n",
    "```"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "眼力好的同学立马会发现这代码写的有问题，比如只要`信贷情况==非常好`的用户都有放款，何必嵌到里面去？而且很多规则有冗余，为什么不重构一下呀？但现实情况是你可能真不敢随意乱动！因为指不定哪天项目经理又要新增加规则了，所以宁可让代码越来越冗余，越来越复杂，也不敢随意乱动之前的规则，乱动两条，可能会带来意想不到的灾难。简单总结一下这种复杂嵌套的`if else`规则可能存在的痛点：  \n",
    "\n",
    "（1）规则可能不完备，存在某些匹配不上的情况；  \n",
    "\n",
    "（2）规则之间存在冗余，多个`if else`情况其实是判断的同样的条件；  \n",
    "\n",
    "（3）严重时，可能会出现矛盾的情况，即相同的条件，即有**放**，又有**不放**；  \n",
    "\n",
    "（4）判断规则的优先级混乱，比如`信贷情况`因子可以优先考虑，因为只要它是`非常好`就可以放款，而不必先判断其它条件  \n",
    "\n",
    "而决策树算法就能解决以上痛点，它能保证所有的规则**互斥且完备**，即用户的任意一种情况一定能匹配上一条规则，且该规则唯一，这样就能解决上面的痛点1~3，且规则判断的优先级也很不错，下面介绍决策树学习算法。"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "### 决策树学习\n",
    "决策树算法可以从已标记的数据中自动学习出`if else`规则集，如下图（[图片来源>>>](https://www.cnblogs.com/jin-liang/p/9609144.html)），左边是收集的一系列判断是否打球的案例，包括4个特征outlook,temperature,Humidity,Wind,以及y标签是否打球，通过决策树学习后得到右边的决策树，**决策树的结构**如图所示，它由节点和有向边组成，而节点又分为两种：叶子节点和非叶子节点，非叶子节点主要用于对某一特征做判断，而它下面所链接的有向边表示该特征所满足的某条件，最终的叶子节点即表示实例的预测值(分类/回归)  \n",
    "\n",
    "\n",
    "![avatar](./source/09_决策树学习.jpg)"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "决策树学习主要分为两个阶段，**决策树生成**和**决策树剪枝**，决策树生成阶段最重要便是**特征选择**，下面对相关概念做介绍：  "
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "#### 1.特征选择  \n",
    "\n",
    "特征选择用于选择对分类有用的特征，ID3和C4.5通常选择的准则是信息增益和信息增益比，下面对其作介绍并实现\n",
    "\n",
    "##### 信息增益\n",
    "首先介绍两个随机变量之间的互信息公式：  \n",
    "\n",
    "$$\n",
    "MI(Y,X)=H(Y)-H(Y|X)\n",
    "$$  \n",
    "\n",
    "这里$H(X)$表示$X$的熵，在最大熵模型那一节已做过介绍：  \n",
    "\n",
    "$$\n",
    "H(X)=-\\sum_{i=1}^np_ilogp_i,这里p_i=P(X=x_i)\n",
    "$$  \n",
    "\n",
    "条件熵$H(Y|X)$表示在已知随机变量$X$的条件下，随机变量$Y$的不确定性：  \n",
    "\n",
    "$$\n",
    "H(Y|X)=\\sum_{i=1}^np_iH(Y|X=x_i),这里p_i=P(X=x_i)\n",
    "$$  \n",
    "\n",
    "而信息增益就是$Y$取分类标签，$X$取某一特征时的互信息，它表示如果选择特征$X$对数据进行分割，可以使得分割后$Y$分布的熵降低多少，若降低的越多，说明分割每个子集的$Y$的分布越集中，则$X$对分类标签$Y$越有用，下面进行python实现：  "
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 1,
   "metadata": {},
   "outputs": [],
   "source": [
    "\"\"\"\n",
    "定义计算熵的函数,封装到ml_models.utils\n",
    "\"\"\"\n",
    "import numpy as np\n",
    "from collections import Counter\n",
    "import math\n",
    "def entropy(x,sample_weight=None):\n",
    "    x=np.asarray(x)\n",
    "    #x中元素个数\n",
    "    x_num=len(x)\n",
    "    #如果sample_weight为None设均设置一样\n",
    "    if sample_weight is None:\n",
    "        sample_weight=np.asarray([1.0]*x_num)\n",
    "    x_counter={}\n",
    "    weight_counter={}\n",
    "    # 统计各x取值出现的次数以及其对应的sample_weight列表\n",
    "    for index in range(0,x_num):\n",
    "        x_value=x[index]\n",
    "        if x_counter.get(x_value) is None:\n",
    "            x_counter[x_value]=0\n",
    "            weight_counter[x_value]=[]\n",
    "        x_counter[x_value]+=1\n",
    "        weight_counter[x_value].append(sample_weight[index])\n",
    "    \n",
    "    #计算熵\n",
    "    ent=.0\n",
    "    for key,value in x_counter.items():\n",
    "        p_i=1.0*value*np.mean(weight_counter.get(key))/x_num\n",
    "        ent+=-p_i*math.log(p_i)\n",
    "    return ent"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 2,
   "metadata": {},
   "outputs": [
    {
     "data": {
      "text/plain": [
       "0.6931471805599453"
      ]
     },
     "execution_count": 2,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "#测试\n",
    "entropy([1,2])"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 3,
   "metadata": {},
   "outputs": [],
   "source": [
    "def cond_entropy(x, y,sample_weight=None):\n",
    "    \"\"\"\n",
    "    计算条件熵:H(y|x)\n",
    "    \"\"\"\n",
    "    x=np.asarray(x)\n",
    "    y=np.asarray(y)\n",
    "    # x中元素个数\n",
    "    x_num = len(x)\n",
    "    #如果sample_weight为None设均设置一样\n",
    "    if sample_weight is None:\n",
    "        sample_weight=np.asarray([1.0]*x_num)\n",
    "    # 计算\n",
    "    ent = .0\n",
    "    for x_value in set(x):\n",
    "        x_index=np.where(x==x_value)\n",
    "        new_x=x[x_index]\n",
    "        new_y=y[x_index]\n",
    "        new_sample_weight=sample_weight[x_index]\n",
    "        p_i=1.0*len(new_x)/x_num\n",
    "        ent += p_i * entropy(new_y,new_sample_weight)\n",
    "    return ent"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 4,
   "metadata": {},
   "outputs": [
    {
     "data": {
      "text/plain": [
       "0.0"
      ]
     },
     "execution_count": 4,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "#测试\n",
    "cond_entropy([1,2],[1,2])"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 5,
   "metadata": {},
   "outputs": [],
   "source": [
    "def muti_info(x, y,sample_weight=None):\n",
    "    \"\"\"\n",
    "    互信息/信息增益:H(y)-H(y|x)\n",
    "    \"\"\"\n",
    "    x_num=len(x)\n",
    "    if sample_weight is None:\n",
    "        sample_weight=np.asarray([1.0]*x_num)\n",
    "    return entropy(y,sample_weight) - cond_entropy(x, y,sample_weight)"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "接下来，做一个测试，看特征的取值的个数对信息增益的影响"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 6,
   "metadata": {},
   "outputs": [
    {
     "data": {
      "text/plain": [
       "[<matplotlib.lines.Line2D at 0x21ed2625ba8>]"
      ]
     },
     "execution_count": 6,
     "metadata": {},
     "output_type": "execute_result"
    },
    {
     "data": {
      "image/png": "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\n",
      "text/plain": [
       "<Figure size 432x288 with 1 Axes>"
      ]
     },
     "metadata": {},
     "output_type": "display_data"
    }
   ],
   "source": [
    "import random\n",
    "import numpy as np\n",
    "import matplotlib.pyplot as plt\n",
    "%matplotlib inline\n",
    "#作epochs次测试\n",
    "epochs=100\n",
    "#x的取值的个数：2->class_num_x\n",
    "class_num_x=100\n",
    "#y标签类别数\n",
    "class_num_y=2\n",
    "#样本数量\n",
    "num_samples=500\n",
    "info_gains=[]\n",
    "for _ in range(0,epochs):\n",
    "    info_gain=[]\n",
    "    for class_x in range(2,class_num_x):\n",
    "        x=[]\n",
    "        y=[]\n",
    "        for _ in range(0,num_samples):\n",
    "            x.append(random.randint(1,class_x))\n",
    "            y.append(random.randint(1,class_num_y))\n",
    "        info_gain.append(muti_info(x,y))\n",
    "    info_gains.append(info_gain)\n",
    "plt.plot(np.asarray(info_gains).mean(axis=0))"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "可以发现一个很有意思的现象，如果特征的取值的个数越多，越容易被选中，这比较好理解，假设一个极端情况，若对每一个实例特征$x$的取值都不同，则其$H(Y|X)$项为0，则$MI(X,Y)=H(Y)-H(Y|X)$将会取得最大值（$H(Y)$与$X$无关），这便是ID3算法的一个痛点，为了矫正这一问题，C4.5算法利用信息增益比作特征选择"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "##### 信息增益比\n",
    "信息增益比其实就是对信息增益除以了一个$x$的熵：  \n",
    "\n",
    "$$\n",
    "\\frac{MI(X,Y)}{H(X)}\n",
    "$$"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 7,
   "metadata": {},
   "outputs": [],
   "source": [
    "def info_gain_rate(x, y,sample_weight=None):\n",
    "    \"\"\"\n",
    "    信息增益比\n",
    "    \"\"\"\n",
    "    x_num=len(x)\n",
    "    if sample_weight is None:\n",
    "        sample_weight=np.asarray([1.0]*x_num)\n",
    "    return 1.0 * muti_info(x, y,sample_weight) / (1e-12 + entropy(x,sample_weight))"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "接下来再作一次相同的测试："
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 8,
   "metadata": {},
   "outputs": [
    {
     "data": {
      "text/plain": [
       "[<matplotlib.lines.Line2D at 0x21ed26da978>]"
      ]
     },
     "execution_count": 8,
     "metadata": {},
     "output_type": "execute_result"
    },
    {
     "data": {
      "image/png": "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\n",
      "text/plain": [
       "<Figure size 432x288 with 1 Axes>"
      ]
     },
     "metadata": {},
     "output_type": "display_data"
    }
   ],
   "source": [
    "#作epochs次测试\n",
    "epochs=100\n",
    "#x的取值的个数：2->class_num_x\n",
    "class_num_x=100\n",
    "#y标签类别数\n",
    "class_num_y=2\n",
    "#样本数量\n",
    "num_samples=500\n",
    "info_gain_rates=[]\n",
    "for _ in range(0,epochs):\n",
    "    info_gain_rate_=[]\n",
    "    for class_x in range(2,class_num_x):\n",
    "        x=[]\n",
    "        y=[]\n",
    "        for _ in range(0,num_samples):\n",
    "            x.append(random.randint(1,class_x))\n",
    "            y.append(random.randint(1,class_num_y))\n",
    "        info_gain_rate_.append(info_gain_rate(x,y))\n",
    "    info_gain_rates.append(info_gain_rate_)\n",
    "plt.plot(np.asarray(info_gain_rates).mean(axis=0))"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "虽然整体还是上升的趋势，当相比于信息增益已经缓解了很多，将它们画一起直观感受一下：  "
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 9,
   "metadata": {},
   "outputs": [
    {
     "data": {
      "text/plain": [
       "[<matplotlib.lines.Line2D at 0x21ed267e860>]"
      ]
     },
     "execution_count": 9,
     "metadata": {},
     "output_type": "execute_result"
    },
    {
     "data": {
      "image/png": "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\n",
      "text/plain": [
       "<Figure size 432x288 with 1 Axes>"
      ]
     },
     "metadata": {},
     "output_type": "display_data"
    }
   ],
   "source": [
    "plt.plot(np.asarray(info_gains).mean(axis=0),'r')\n",
    "plt.plot(np.asarray(info_gain_rates).mean(axis=0),'y')"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "#### 2.决策树生成\n",
    "决策树的生成就是一个递归地调用特征选择的过程，首先从根节点开始，利用信息增益/信息增益比选择最佳的特征作为节点特征，由该特征的不同取值建立子节点，然后再对子节点调用以上方法，直到所有特征的信息增益/信息增益比均很小或者没有特征可以选择时停止，最后得到一颗决策树。接下来直接进行代码实现：  "
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 10,
   "metadata": {},
   "outputs": [],
   "source": [
    "import os\n",
    "os.chdir('../')\n",
    "from ml_models import utils\n",
    "from ml_models.wrapper_models import DataBinWrapper\n",
    "\"\"\"\n",
    "ID3和C4.5决策树分类器的实现，放到ml_models.tree模块\n",
    "\"\"\"\n",
    "class DecisionTreeClassifier(object):\n",
    "    class Node(object):\n",
    "        \"\"\"\n",
    "        树节点，用于存储节点信息以及关联子节点\n",
    "        \"\"\"\n",
    "\n",
    "        def __init__(self, feature_index: int = None, target_distribute: dict = None, weight_distribute: dict = None,\n",
    "                     children_nodes: dict = None, num_sample: int = None):\n",
    "            \"\"\"\n",
    "            :param feature_index: 特征id\n",
    "            :param target_distribute: 目标分布\n",
    "            :param weight_distribute:权重分布\n",
    "            :param children_nodes: 孩子节点\n",
    "            :param num_sample:样本量\n",
    "            \"\"\"\n",
    "            self.feature_index = feature_index\n",
    "            self.target_distribute = target_distribute\n",
    "            self.weight_distribute = weight_distribute\n",
    "            self.children_nodes = children_nodes\n",
    "            self.num_sample = num_sample\n",
    "\n",
    "    def __init__(self, criterion='c4.5', max_depth=None, min_samples_split=2, min_samples_leaf=1,\n",
    "                 min_impurity_decrease=0, max_bins=10):\n",
    "        \"\"\"\n",
    "        :param criterion:划分标准，包括id3,c4.5，默认为c4.5\n",
    "        :param max_depth:树的最大深度\n",
    "        :param min_samples_split:当对一个内部结点划分时，要求该结点上的最小样本数，默认为2\n",
    "        :param min_samples_leaf:设置叶子结点上的最小样本数，默认为1\n",
    "        :param min_impurity_decrease:打算划分一个内部结点时，只有当划分后不纯度(可以用criterion参数指定的度量来描述)减少值不小于该参数指定的值，才会对该结点进行划分，默认值为0\n",
    "        \"\"\"\n",
    "        self.criterion = criterion\n",
    "        if criterion == 'c4.5':\n",
    "            self.criterion_func = utils.info_gain_rate\n",
    "        else:\n",
    "            self.criterion_func = utils.muti_info\n",
    "        self.max_depth = max_depth\n",
    "        self.min_samples_split = min_samples_split\n",
    "        self.min_samples_leaf = min_samples_leaf\n",
    "        self.min_impurity_decrease = min_impurity_decrease\n",
    "\n",
    "        self.root_node: self.Node = None\n",
    "        self.sample_weight = None\n",
    "        self.dbw = DataBinWrapper(max_bins=max_bins)\n",
    "\n",
    "    def _build_tree(self, current_depth, current_node: Node, x, y, sample_weight):\n",
    "        \"\"\"\n",
    "        递归进行特征选择，构建树\n",
    "        :param x:\n",
    "        :param y:\n",
    "        :param sample_weight:\n",
    "        :return:\n",
    "        \"\"\"\n",
    "        rows, cols = x.shape\n",
    "        # 计算y分布以及其权重分布\n",
    "        target_distribute = {}\n",
    "        weight_distribute = {}\n",
    "        for index, tmp_value in enumerate(y):\n",
    "            if tmp_value not in target_distribute:\n",
    "                target_distribute[tmp_value] = 0.0\n",
    "                weight_distribute[tmp_value] = []\n",
    "            target_distribute[tmp_value] += 1.0\n",
    "            weight_distribute[tmp_value].append(sample_weight[index])\n",
    "        for key, value in target_distribute.items():\n",
    "            target_distribute[key] = value / rows\n",
    "            weight_distribute[key] = np.mean(weight_distribute[key])\n",
    "        current_node.target_distribute = target_distribute\n",
    "        current_node.weight_distribute = weight_distribute\n",
    "        current_node.num_sample = rows\n",
    "        # 判断停止切分的条件\n",
    "\n",
    "        if len(target_distribute) <= 1:\n",
    "            return\n",
    "\n",
    "        if rows < self.min_samples_split:\n",
    "            return\n",
    "\n",
    "        if self.max_depth is not None and current_depth > self.max_depth:\n",
    "            return\n",
    "\n",
    "        # 寻找最佳的特征\n",
    "        best_index = None\n",
    "        best_criterion_value = 0\n",
    "        for index in range(0, cols):\n",
    "            criterion_value = self.criterion_func(x[:, index], y)\n",
    "            if criterion_value > best_criterion_value:\n",
    "                best_criterion_value = criterion_value\n",
    "                best_index = index\n",
    "\n",
    "        # 如果criterion_value减少不够则停止\n",
    "        if best_index is None:\n",
    "            return\n",
    "        if best_criterion_value <= self.min_impurity_decrease:\n",
    "            return\n",
    "        # 切分\n",
    "        current_node.feature_index = best_index\n",
    "        children_nodes = {}\n",
    "        current_node.children_nodes = children_nodes\n",
    "        selected_x = x[:, best_index]\n",
    "        for item in set(selected_x):\n",
    "            selected_index = np.where(selected_x == item)\n",
    "            # 如果切分后的点太少，以至于都不能做叶子节点，则停止分割\n",
    "            if len(selected_index[0]) < self.min_samples_leaf:\n",
    "                continue\n",
    "            child_node = self.Node()\n",
    "            children_nodes[item] = child_node\n",
    "            self._build_tree(current_depth + 1, child_node, x[selected_index], y[selected_index],\n",
    "                             sample_weight[selected_index])\n",
    "\n",
    "    def fit(self, x, y, sample_weight=None):\n",
    "        # check sample_weight\n",
    "        n_sample = x.shape[0]\n",
    "        if sample_weight is None:\n",
    "            self.sample_weight = np.asarray([1.0] * n_sample)\n",
    "        else:\n",
    "            self.sample_weight = sample_weight\n",
    "        # check sample_weight\n",
    "        if len(self.sample_weight) != n_sample:\n",
    "            raise Exception('sample_weight size error:', len(self.sample_weight))\n",
    "\n",
    "        # 构建空的根节点\n",
    "        self.root_node = self.Node()\n",
    "\n",
    "        # 对x分箱\n",
    "        self.dbw.fit(x)\n",
    "\n",
    "        # 递归构建树\n",
    "        self._build_tree(1, self.root_node, self.dbw.transform(x), y, self.sample_weight)\n",
    "\n",
    "    # 检索叶子节点的结果\n",
    "    def _search_node(self, current_node: Node, x, class_num):\n",
    "        if current_node.feature_index is None or current_node.children_nodes is None or len(\n",
    "                current_node.children_nodes) == 0 or current_node.children_nodes.get(\n",
    "            x[current_node.feature_index]) is None:\n",
    "            result = []\n",
    "            total_value = 0.0\n",
    "            for index in range(0, class_num):\n",
    "                value = current_node.target_distribute.get(index, 0) * current_node.weight_distribute.get(index, 1.0)\n",
    "                result.append(value)\n",
    "                total_value += value\n",
    "            # 归一化\n",
    "            for index in range(0, class_num):\n",
    "                result[index] = result[index] / total_value\n",
    "            return result\n",
    "        else:\n",
    "            return self._search_node(current_node.children_nodes.get(x[current_node.feature_index]), x, class_num)\n",
    "\n",
    "    def predict_proba(self, x):\n",
    "        # 计算结果概率分布\n",
    "        x = self.dbw.transform(x)\n",
    "        rows = x.shape[0]\n",
    "        results = []\n",
    "        class_num = len(self.root_node.target_distribute)\n",
    "        for row in range(0, rows):\n",
    "            results.append(self._search_node(self.root_node, x[row], class_num))\n",
    "        return np.asarray(results)\n",
    "\n",
    "    def predict(self, x):\n",
    "        return np.argmax(self.predict_proba(x), axis=1)"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 11,
   "metadata": {},
   "outputs": [],
   "source": [
    "#造伪数据\n",
    "from sklearn.datasets import make_classification\n",
    "data, target = make_classification(n_samples=100, n_features=2, n_classes=2, n_informative=1, n_redundant=0,\n",
    "                                   n_repeated=0, n_clusters_per_class=1, class_sep=.5,random_state=21)"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 12,
   "metadata": {},
   "outputs": [
    {
     "data": {
      "image/png": "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\n",
      "text/plain": [
       "<Figure size 432x288 with 1 Axes>"
      ]
     },
     "metadata": {},
     "output_type": "display_data"
    }
   ],
   "source": [
    "#训练查看效果\n",
    "tree = DecisionTreeClassifier(max_bins=15)\n",
    "tree.fit(data, target)\n",
    "utils.plot_decision_function(data, target, tree)"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "可以发现，如果不对决策树施加一些限制，它会尝试创造很细碎的规则去使所有的训练样本正确分类，这无疑会使得模型过拟合，所以接下来需要对其进行减枝操作，避免其过拟合"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "#### 3.决策树剪枝\n",
    "顾名思义，剪掉一些不必要的叶子节点，那么如何确定那些叶子节点需要去掉，哪些不需要去掉呢？这可以通过构建损失函数来量化，如果剪掉某一叶子结点后损失函数能减少，则进行剪枝操作，如果不能减少则不剪枝。一种简单的量化损失函数可以定义如下：  \n",
    "\n",
    "$$\n",
    "C_\\alpha(T)=\\sum_{t=1}^{\\mid T\\mid}N_tH_t(T)+\\alpha\\mid T\\mid\n",
    "$$"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "这里$\\mid T \\mid$表示树$T$的叶结点个数，$t$是树$\\mid T \\mid$的叶结点，该叶节点有$N_t$个样本点，其中$k$类样本点有$N_{tk}$个，$k=1,2,3,...,K$，$H_t(T)$为叶结点$t$上的经验熵，$\\alpha\\geq 0$为超参数，其中：  \n",
    "\n",
    "$$\n",
    "H_t(T)=-\\sum_k\\frac{N_{tk}}{N_t}log\\frac{N_{tk}}{N_t}\n",
    "$$  \n",
    "\n",
    "该损失函数可以分为两部分，第一部分$\\sum_{t=1}^{\\mid T\\mid}N_tH_t(T)$为经验损失，第二部分$\\mid T \\mid$为结构损失，$\\alpha$为调节其平衡度的系数，如果$\\alpha$越大则模型结构越简单，越不容易过拟合，接下来进行剪枝的代码实现：  \n",
    "\n",
    "```python\n",
    "    def _prune_node(self, current_node: Node, alpha):\n",
    "        # 如果有子结点,先对子结点部分剪枝\n",
    "        if current_node.children_nodes is not None and len(current_node.children_nodes) != 0:\n",
    "            for child_node in current_node.children_nodes.values():\n",
    "                self._prune_node(child_node, alpha)\n",
    "\n",
    "        # 再尝试对当前结点剪枝\n",
    "        if current_node.children_nodes is not None and len(current_node.children_nodes) != 0:\n",
    "            # 避免跳层剪枝\n",
    "            for child_node in current_node.children_nodes.values():\n",
    "                # 当前剪枝的层必须是叶子结点的层\n",
    "                if child_node.children_nodes is not None and len(child_node.children_nodes) > 0:\n",
    "                    return\n",
    "            # 计算剪枝前的损失值\n",
    "            pre_prune_value = alpha * len(current_node.children_nodes)\n",
    "            for child_node in current_node.children_nodes.values():\n",
    "                for key, value in child_node.target_distribute.items():\n",
    "                    pre_prune_value += -1 * child_node.num_sample * value * np.log(\n",
    "                        value) * child_node.weight_distribute.get(key, 1.0)\n",
    "            # 计算剪枝后的损失值\n",
    "            after_prune_value = alpha\n",
    "            for key, value in current_node.target_distribute.items():\n",
    "                after_prune_value += -1 * current_node.num_sample * value * np.log(\n",
    "                    value) * current_node.weight_distribute.get(key, 1.0)\n",
    "\n",
    "            if after_prune_value <= pre_prune_value:\n",
    "                # 剪枝操作\n",
    "                current_node.children_nodes = None\n",
    "                current_node.feature_index = None\n",
    "\n",
    "    def prune(self, alpha=0.01):\n",
    "        \"\"\"\n",
    "        决策树剪枝 C(T)+alpha*|T|\n",
    "        :param alpha:\n",
    "        :return:\n",
    "        \"\"\"\n",
    "        # 递归剪枝\n",
    "        self._prune_node(self.root_node, alpha)\n",
    "```"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 13,
   "metadata": {},
   "outputs": [
    {
     "data": {
      "image/png": "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\n",
      "text/plain": [
       "<Figure size 432x288 with 1 Axes>"
      ]
     },
     "metadata": {},
     "output_type": "display_data"
    }
   ],
   "source": [
    "from ml_models.tree import DecisionTreeClassifier\n",
    "#训练查看效果\n",
    "tree = DecisionTreeClassifier(max_bins=15)\n",
    "tree.fit(data, target)\n",
    "tree.prune(alpha=1.5)\n",
    "utils.plot_decision_function(data, target, tree)"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "通过探索$\\alpha$，我们可以得到一个比较令人满意的剪枝结果，这样的剪枝方式通常又被称为**后剪枝**，即从一颗完整生成后的树开始剪枝，与其对应的还有**预剪枝**，即在训练过程中就对其进行剪枝操作，这通常需要另外构建一份**验证集**做支持，这里就不实现了，另外比较通常的做法是，通过一些参数来控制模型的复杂度，比如`max_depth`控制树的最大深度，`min_samples_leaf`控制叶子结点的最小样本数，`min_impurity_decrease`控制特征划分后的最小不纯度，`min_samples_split`控制结点划分的最小样本数，通过调节这些参数，同样可以达到剪枝的效果，比如下面通过控制叶结点的最小数量达到了和上面剪枝一样的效果：  "
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 14,
   "metadata": {},
   "outputs": [
    {
     "data": {
      "image/png": "iVBORw0KGgoAAAANSUhEUgAAAXYAAAD8CAYAAABjAo9vAAAABHNCSVQICAgIfAhkiAAAAAlwSFlzAAALEgAACxIB0t1+/AAAADl0RVh0U29mdHdhcmUAbWF0cGxvdGxpYiB2ZXJzaW9uIDIuMi4yLCBodHRwOi8vbWF0cGxvdGxpYi5vcmcvhp/UCwAAIABJREFUeJzs3Xd4FNX6wPHvbN9N7wmp9B5C770pVYqoqGBBRAUbV+zda8GKDQUEARGliYIgvUhvIRBaaCEQQkiv22d+f+SamB8gATZZiOfzPPd5rsPMOe9uNm/OnjnzHklRFARBEITqQ+XuAARBEATXEoldEAShmhGJXRAEoZoRiV0QBKGaEYldEAShmhGJXRAEoZoRiV0QBKGaEYldEAShmhGJXRAEoZrRuKPTgEAvJTIqyB1dC4Ig3LIS4k9nKopy1eTplsQeGRXEus1vu6NrQRCEW1ag131nKnKemIoRBEGoZkRiFwRBqGZEYhcEQahmRGIXBEGoZkRiFwRBqGZEYhcEQahmRGIXBEGoZkRiFwRBqGZEYhcEQahmRGIXBEGoZkRiFwRBqGZEYhcEQahmRGIXBEGoZkRiFwRBqGZEYhcEQahmRGIXBEGoZkRiFwRBqGZEYhcEQahmRGIXBEGoZkRiFwRBqGZEYhcEQahmRGIXBEGoZkRiFwRBqGZEYhcEQahmRGIXBEGoZkRiFwRBqGZEYhcEQahmRGIXBEGoZkRiFwRBqGZEYhcEQahmRGIXBEGoZkRiFwRBqGZEYhcEQahmRGIXBEGoZkRiFwRBqGY0N9qAJEmRwBwgFJCBaYqiTLnRdgX3yc8rZtXKfaSeS6dmrXB69Y3Dw8Pg7rAEQaggV4zYHcBERVEaAu2AJyRJauSCdgU3OJN8kUdGf8DZo2tpGH6UxF0rePSBj8jIyHN3aIIgVNANJ3ZFUdIURdn3v/9fABwBwm+0XcE9vv1yKQ/cqeP1STUYPjiI91+L4PZuMrOmrXR3aIIgVJBL59glSYoBmgM7XdmuUDXsdgf79iQxuF9AueNDB/izY9tBN0VVuWRZJvn0RS5cyHF3KILgMjc8x/4XSZI8gcXA04qi5F/m38cCYwEiIgP+/z8LNwG1WoVarcJildHry/7mF5tl9DqtGyOrHLt2JPH5xz+jkcwUm2UioiOZ9MpIQkP93B2aINwQl4zYJUnSUpLU5ymKsuRy5yiKMk1RlFaKorQKCPR2RbeCi6lUKrr2aMG02RdRFAUAWVaYPjeD7r3b3FDbZrONHduOsWtHEjabwxXh3pDUc1lMfmcWrz1jYvH3MSybV5POLXJ49fkZyLLs7vAE4YbccGKXJEkCvgOOKIryyY2HJLjTYxMGcTjZn5GPnuGtD88z7IHT5FujGPVQr+tuc/PGREYOe5Ol8+exYPZc7h3+Fvv2nHRh1Ndu5fJdDOxtpGWcFwAajcT9dwWhlnM5eOCMW2MThBvliqmYjsD9wEFJkvb/79hLiqKscEHbQhXz8jYx5esJHDxwhtRzWfS7K5T6Da7/Xnh6ei6fTZ7HV++HUL+OCYB9CQU8//pMZv/0Cl5eRleFfk2ys3Jp3aD8x1+SJCLDtWRnFbolJkFwFVesitmiKIqkKEqsoihx//ufSOq3MEmSiG0Ww+39W95QUgfYsOYAvbvqS5M6QItmXrRsqmHL5sM3Gup1a9SkNhu2mkunnAAKi5zsO2CmYeMIt8UlCK4gnjwVKlVxsQVfb+mS436+EsXFVjdEVKJX3zjSc3x5Y3Iq+xIK2Lgll/HPn6XHbR3FzVPhlicSu1CpWrWtx5pNFiyWshuS+QUONm4107pNXbfFZTDo+PiLJwiO6coX36v4eYUng+4aweMTBrotJkFwFZctdxSEy2kaG03D2DjGPJ3A0P4eOBywcFkhvW7vQlR0kFtj8/Q0MOrBnox6sKdb4xAEVxOJXahUkiQx8YU72b4tlq2bElCrVTwxsQUtWtV2d2iCUG2JxC5UOpVKRcdODenYqaG7QxGEfwUxxy4IglDNiMQuCIJQzYjELgiCUM2IOXahWjl86Cw/zFpJ0rEUQkL8GTqiJz37NHN3WIJQpcSIXag2jh45x2vPf02fDlnM+zqMJ0bJ/DhrPksXb3N3aIJQpcSIXag2fpq7hnGjvBh4W0lZ6MAALe+/quWJF/9gwOC2aDTq0nNlWWbv7pMcOXyOoGBvunZvgsmkd1foguBSYsQuVBsnjp+lVXPPcsdqxRiRFBs5OWWFvaxWOy88O41ZX89CXbyJPZt+5aGR73Hq5IWqDlkQKoUYsQvVRo3wII4ezyMyvGzj7fSLNmwOFT4+HqXHFv28BS9tKl99FY1KVVLH5reVWXz6wU98Me3pKo9bEFxNjNiFamP43T35fHou8QcKUBSFs6kW3picxsAhXdHpysYwWzbt5d47/UqTOsCAvv6kpaaJTbuFakGM2IVqo027ejzyxEjembKcrMwL6PR6Bg3txv0PlK8FIwF/q9YrCNWOSOyCW50+lc72rUfR6jR07d6E4GCfG2qve69YuvVsSlGRFaNRh1p96ZfSzt1bM3fhWpo28kCtLpuKCYuoQVDQjfUvCDcDkdgFt5k5bRWrf99A764Gsi0K42Yv4/Gn7qZX37gbaleSJDw9DVf892EjOvLavmPc91gyHVvrOX3WybGTat775J4b6lcQbhYisQtucfjQWdb/sYEfv43Cx7vkY3jXHWbGTvyZNu3q4e1jukoL10+n0/Dex48Qv/cURw6fo0N9b55/uzFGo67S+hSEqiQSu3BdcrILWb1yH+fPX6R2nUh69Y27pnXgf248wKC+ptKkDiVLE1s107Fj+zH63Na8MsIuJUkSLVrVFuWDhWpJrIoRrtmJ42mMfWAy6afX0yTqGAd2/M5jD31MVmbBNbVzpRuYknTpVnqCIFScSOzCNft6ymIeG2Xk5WdrMHRgEB+8HkG3tnbmzFpd4Ta6dI/lt1XF5OTaS4+dTDazJ8FGu/b1KiNsQfjXEFMxwjUpLraSdPQM/d+tU+74kAF+PDbpIDCsQu00bBRJ7wE9GPnoenp1MWC2KGzabuPJiffg5V158+uC8G8gErtwTUqWD0pYrDKef6u9UlQsozdor6mtBx7uQ/eecezYdoxAnYZp4xoTGOTt4ogF4d9HJPYqJssyu3eeICH+JL6+nvTsE0dAoJe7w6owvV5Lu46xzJh7kqceDUWSJBwOhRlzM+neu9s1txcdE0x0TLDrAxWEfzExx16F7HYHL0/6jtnffE+AbjcXk9cxdvR77Nt70t2hXZPxTw8h/qgPIx89wxsfnGfo6NMoujrcc183d4cmCAJixF6lVi7fi2Q9w/dfRpc+8dirSz5vvzuPuQtfQaW6Nf7O+vp58MW3T3EgIZm08zkMvi+MOnXD3B2WIAj/IxJ7Fdr2ZzwjBnmXJnWA1i288TDmcDwpjfoNwt0Y3bWRJIlmcTVpFlfT3aFUiCzLmM02TCa9WE4pVHsisVchtUaN3VF+8baiKNjt8mVrmgg3TpZl5v+wkV8WbsBqseDn78PohweK7fKEak0k9irUrWdr5i1YQMc23hiNJStK1mzMQdL4ULtOqJujq57mzVlP/Lb1TP84lMhwPQcPF/Hqe/MxmvR06NTA3eEJQqUQib0K9ewdy4H9xxkxZi+d2hpIS5c5flrF25PHiumBClAUhdV/7GftH9uxmC20ahfLsBGdrljwy+FwsnTRRmZ+FkZEjZJyB7GNPXlmnIN5P62tksSuKApOp1xuWz5BqGwisVchlUrFxOfv5OSJzhxISKZhaw9e6dQAvf7a1n//W331+W8cS9jJg/f44u2l5teVm5k4IYEpUyegVqtIPJiCoig0jY1Gq9VQWGBBcdpKk/pfGtQzkZaaUamx/jUFtHTRRvLzioipFcpDYwfTVjxVK1QBkdjdoHadUDH1co3S0nLYsGobS2bH4OlRMvqNa+rJs6+eY9rUVWzZuIewIBkJhfMZaia9fD8tWtVCbzBx7EQx9euUPc26e18BNetEVGq8389YzaG9m5n6QQjRkeHs2JPP2+/O5JV3xhHbLKZS+xYEl9yxkyRppiRJFyVJSnRFe4Lw/x09fI6WzYylSR1KVua0aa5j0fw/eOd5b2Z+Hsl3n0fx7ovevPvmLPLzzNz3YD9e/u8Ftu/OIyvbzoo1WXw1M597R/ettFgtFhvLl27mnZdqUDPaiEol0aGND48/6MPC+esqrV9B+IurRuzfA18Cc1zUniCU4x/gSUqqHUVRyt2P2PBnPl3bm2gZV/b0bvNYLzq2ymfjhoPcMbQdJg8jU+euIT09jTp1I3nt3ZE0bhJVabHmZBfiYVQIDipf371xAxOzF12otH4F4S8uSeyKomyWJCnGFW0JwuU0jY3GKfky56cM7r0zCLUa9u4vZMc+Cw/c5XfJ+YH+KgoLLAB079mU7j2bVlmsAYHeFFlUpKZZCQ8rm9/fl1BITK3KnQISBBAlBf5VlFt4B2eVSsU7kx9hS7wf/e85ydDRp3n7s2KemXQPm7bbMJudpedaLDLr/jTTqk2df2ix8uh0Gu68pxcvvHWeA4cKKSxysnJtNjPmFXL3fb3cEpPw71JlN08lSRoLjAWIiAyoqm7/9UpWZ2xi2ZJNZGUX0KhxNA89OvCWeWL07+w2Bx6eBnLzHBQUquh9e3363hbHmdOpjH02njsHeSJJEgt/KyC2ZQu3Psl7973d0Gp1PP3K72Rl5hJaI4gnn7v3lnq6uLo5djSVdWv2YbfZad+xCa3b1q22y4wlV43i/jcVs1xRlCZXOzeuRS1l3ea3XdKv8M++/Wo5Jw9t57nxwURFGNiwJYePvs7jvY8nULd+DXeHV2EF+cWMHf0hI4eoGdI/ALNFZtrsixw/F8THXzzG1i1H2bx+HwBderSgRctarF2VQGLCMXz8fbm9f5sqrWeTm1PEs+O/oGZ4MR3bGDhx2s7qTTbefP/RSp3fFy5vwY+bWbpwBUNuN2E0SPy2upg6DZvx3Et33VLJPdDrvr2KorS62nliuWM1Vlho4Y/lW1gwIxJ/v5K18r27+ZOV5WDxgo288OpIN0dYcav/2E+LpjIjh5ckZ6NRzfNP1eCesWc4fOgcXbo2pkvXxkDJ65444StqBOTSq6sH59NSeOnZHTzxzEi69qiaufYff1hPm1gLz00om1OPa5LD5x8v4JuZE2+pZHKry8jI46e5K5j3TUTpDe0hA2QemHCA+L2tq+W+t65a7jgf2A7UlyTpnCRJD7uiXeHGXEzPJShAXZrU/xLb2IOU5PNuiur6nDt7gdiG5VeZSJJEkwZ6zp4p/7DRr0u2Uzsijw/fjOC2nv48dF8In7wVzFdTFmK3O6ok3t3bDzK4n2+5Y907+5Jx4SLZWYVVEoNQYs+uE7RvbSi3SslgUNGvp5Ed2w+7MbLK46pVMfe4oh3BtUJCfcnIksnOsZdL7vsTi4iKufwoRVEU9u05ycb18SiyTMcuzWjXob7bR5gxNWuwb08CwweXHTt+spgVa7K5L6oQm82BTlfycd63K5GHR3iXi7lhfQ/8vDI5fTKden+b57bZHPzx+152bk/AYDDQq28bl7xevUFLUZGz3DGbTcHhBJ1OlBeoSgaDjsIi+ZLjhUUKBr3+Mlfc+sSqmGrMw8NAv0GdeeGtVJJOFmOxyKxcm83sBUUMv7vbZa+ZPnUFX338HQ3Dk2gac4Lvp87hk8mL3L6iplffOA4d1zJ9zgUys2y88MYJHnziMO1bqjm0Zx0P3vMeyacvAmDyNJGTV35k7nQq5BU40eo1bPnzML8t3cXRI+d4ceJ0dm1axpCeOXRqdo4ZX85m1oyKb8p95Xg7MGNuNlZrSUJRFIVZP16kWYsGYk/XKta2fT0OHpWJP1BQeuzceSvLVhfTo3ecGyOrPC67eXotxM3TqiPLMgvn/8lvv2wiK7OAxk1jeHDsAJo0jb7k3OTTF5n05Mf8PCMab6+S0a/Z7OTecSlMev0xt9/0S0/P5btvfmfF8t1EhlqZ+lEM4eG+qFQSv67IYsEKHVO/e5Ytfx5hzrdz+XpyBP5+WhRFYe7PGazcZKC42EJYkJXoCDXrNuVhsdjYuKwpGk3JGCc3z8GdD53hm9kvERzsc92xOp0yH733M3t37qdlMyMnk21o9EG8M3kM/gG3zlaI1cW+PSf57xuzqFdLhckosTfByiOPD6X/oDbuDu2aVPTmqUjst4CCAjNr/ojnTPJ5IqPC6Ht780oZ9S1asI2M06uZNKH8aplvZp3Hpu/Eg2Oubw12YaGFzIx8QkJ9MRrL5jlzc4rYt/ckWp2G1m3qYDDo/qGVMpOensrd/Qvo2rFsDluWFQbff5oPpvyHiMgA5sxay9KF62jSQE9auh21PgCnQ2FEfxvDBgUCkJKSxSv/PcvQgeHcMSCotK0X306lbY+h9Ox94zXbU85kcOxoKiGhvjSNjXb7lNa/mcViY/euE9htDlq1roO3z633zUmsiqkm0tJymPjEF8Q1dhLXWMeBwwcZ+9NaPvpiPOERrn0ewGTUkZd/6R/63HwIjLr2uUiHw8k3Xy1n7crt+Pupyc1TGHpXT+4d1YNlS3fx0dvL8cYPp+LAbihm8pf306Ll1VcoOB0OdLryCVKSQKdTYbc7kCSJ0Q/1ZtAd7Tly+Bx+/h74+HrwzLgPGDKgFgAXM2wkJFro0t7Iqg1Z5RL7xUwn3i76wxkVHURUdNDVTxQqncGgo3OXRu4Oo0qIxH6Tm/71Mob1k3hgZMkNv2GD4IcFF5n21W+8+d6DLu2rc9dGTJ+6hP0HC4lr6gnAsRPFrPvTyrezY6+5vTkz15J2cjeLZ0Xh66PhwkUbk95Yh9XqZPbXW2hubIeHzgOAjKIMJo2fy7L1L5Ub1V9Ou07NWbRsFW1beqNSlST4HXvycSomYmoGl57n5+9ZWnP9bEomWo0KRVF49+MzLF+VQd1aWk6dsZFfoJCX78DbS83yVdlk5hqq5RI44d9DJPabROq5LDIz86lVK6TcNMvObYd4dXz5+fChAwKY+v3hSwpi3SgvbxMvv/EQz789m5qROWg0EkdPOHlm0r0EBV3bfLMsyyxbupk5X4bi61PyMQsN1vHsY4FMeHEtAc6apUkdIMgjiNR8T3btSKJr939+xm3QkLbs2HqQR55OoXsnA+fSnGzYaueVt8dccUPwiMgAdEYfXnjrFMeO5TLv62ACAzTk5Tv49Jtcegw+SK2afqi0Prwz+WGxVaFwSxOJ3c0KCsy899Y8Thw9TmS4nlNnbNxxZ09GPdgLSZLQ6TUUFTtLb2YCFBU70es1lTJf26pNHeYteo39+07jdMq81rLWVUfQl2O1OrBarIQGl782KkJPYaEZk3LpR0+NGrPZdtW29Xotkz97lG1bj3Iw4RSBUT58+0gcAYFXvikpSRLPPH8Po+96k6kfBBITpUOWFUxGHROfCGTVpjQmPDeGuBY1xTy4cMsTid3NPvtwEREB5/jkh5potSqysu08+eJ6wiOC6dWnGT37tuHb7/fy2nPhqFQSsqzw7eyL9OjTutJi0uu1N7zTj8GgJSIqhJ1782nfumy0v3lbHo2a1CJp7wWcci3UqpI13Wa7mVwli9Zt6laofbVaRecujS47ZyrLMju3J7F3TxJeXiZ6921OjfAAmsZGo1ariIrQoygq1GoJlVpFjRAZSXISHukvkrpQLYjvm25UkF/Mnp0HmTAmBK225EcR4K9l3AN+rPztTwAeeuQ20vNqMOLhZN6cnMZdY86QcjGUMeP6uTP0q5IkiYcfHcxbH2Xxy/JMjiQV88OCi0ydXcjTz91J1wH12J23jRPZJziafYx9RTuYMOm2fxx1V4TTKfP6S7OZO20OkT4JOHO3MmHsh2zeWLIHjE5v5Pe1RWi1atRqFRLw585iHA41gYHeLnjlguB+YsTuRoVFVjxMKkym8k8iBgfpyMsreZjCZNLzwaePcvTIOZJPX6Tv8CAaNY68JUaWbdvX4/X3HmfRTxtYtDKdmrVr8+HnPahZK4TX3hnB7oHH2bTuMHqDhr79B7ik8uH6tQcoyjnBrC+i0WhK3qO+PYuZ8NJ82rZ/gyHDu/LD4tUUFCh0bGvkRLKN6XPz6N63/RXn5wXhViMSuxuFhPig0niUW4UCsHp9HrEtytZQS5JEw0aRNGwU6Y4wb0jjJlE0fmf0JcclSaJNu3q0aefazZ23/7mfof29SpM6QIO6JmIiVBw6mML4ZwaRnp7FsrWJ/LmrgJxchSZxTXn9rXtdGocguJNI7G6kUqkYN2EYL74zh/uGF1MzWs+fO4rYulvFZ990d3d4tyStTovF4rzkuNkio9GqMRh0fPjZo5w4nsaZ5ItERQXdUuWLBaEiRGJ3s05dGhEcPIFlS7eyPSGLeo2a8eX0Dvj5e179YuESPXq3ZtrnifTs6le6kmjjllzyiww0aVpWEqFO3bAqrc8uCFVJJPabQL0G4Ux8YYS7w6gW2rSrS+KBLtz50EY6tDaSmS1z4ozE2x+MFXPowr+GSOxCtVKyGud2+g1sy749J2nlbaRt+/ro9dqrX+xCTqfM0SPnUBSFBg0j0GhEqV6h6ojE7kYHEpKZPeN3jh1JITDImzuG92Dw0Ha3xIqXm11YDX/6D/J3S98J+0/zwVtz8PGyIUkSOXlannvlvgrVwbkeG9cfLNnTNiuPxk3rcM/9PYmIDKyUvoRbg/hu6ibHjqby9svfMqxvASt/iuGt/5hY9/sy5s1Z7+7QhBtQkF/MW698x0tPmfhhajRzv47i9YkevPPaTPJyi1ze36KftzB3+o/cd0cxH77qSa3gJJ55Ygpp57Nd3pdw6xCJ3U0W/LiOMfd60reHPyaTmsYNPXjv1TAW/7wOq9Xu7vBuaoqikJtTdFO+T5s3HqJ1M3W5p21bt/CmYysNG9YfdGlfVqudH+es5JO3a9Clgy+1Yow8MDKEIbdpWTB/o0v7Em4tYirGTc6cTmXsXeVXvoSF6PEyQWZG/nWX5E05k8Hy33aQmZ5F/Ya16Dew1Q3VbpdlmQXztzJ/1layswpp1jKaCf/p55KHia7Hjm3HmP71L2RnZSPLKrr3bs248QMrXMu9shUUmAkKuHQqLThQIj/P7NK+Us9lEegHETXKl1Tu1NaLD6aedmlfwq1FjNjdJCIylMTD5b+aX8ywUVjMde+ws2fXCSY+8Sm+6nj6dLjA2aR1PPHIZ+RkX//myd98vooZ7/9Jjfz6tPPoSvZuHePun1a6DV1VOnY0lU/e+56JYzWsWVSbRTMjseYm8MkHC6s8litp3rI2m7ZZsVjK9ti02WTWb7HSolUtl/YVEOBFRpbjkr1VT5w2ExxSfmCQlpbDiuV72bzp0E35TUdwLZHY3WT4PT34dk4+f27PRZYVTiWbeeXd8wy4o8t1VVOUZZkvP13Am5P8efSBUHp38+fN58Pp1MrGj3PXU5BfjCxfuqHvPykoMPPznG3EerfAz+iHVq0lxjeaAEs4877ffE1tKYrC6VPpHD92/prj+MvSRZsZPcKDtq1KNqr299Py8jNh7NlxgMyM/EvOT0/PZfbMtXz64SJWrYzHZnNcplXXqt8gnKYt4hj3nxRWrs1m5dpsxk1MoW6jJi7fWtDH14P2nZrz7mfnycsveW2Jh4uYMS+fwcO7AiXv+8xpqxj/8Psc2b2MPxb/zP0j3uHokXMujUW4uYipGDdp0jSa5155mOnTl/Hcm0n4+Xlwx/De3H1v1+tq7+LFPCzF+bRpWbPc8U5ttTz85O+sWbkFk8mDkaNvY8DgthVq80JaDjoMGDSGcscDDAEcS0ytcGynTl7gvTfnYC3OQa9XUWzRM/HFey+7mcXpU+ksWbCJcylpRNeKZNiILkRGlazwuHghg7o9jOXONxrVhNfQkZGRR2BQWRGvfXtP8u7r39G3m55GERo2rUzgtyWbmPzZODw8yr8eV5v4wp1s2tCIdev3oigKA++6nR69mlbKaqcnJw7l6881DBm9G6NBQq0xMebxe4hrXvI52LPrBFvWb2ThzGh8vEt+3Tdvy+XtV2YxZ8HLou58NSUSuxu1bluX1m2fRZblG354xmTUY7bIWK0KBkNJAsnJLiTtfD5xTQz8MK0OR48X8+p7v2Aw6OnV9+q7s4eG+mJVLNicNnTqsm8ROZYcGtcPqVBcNpuDlyZ+Q9s4O6kpMg6HTPOWEm+/OoNpc14ot4HHwQNneOulbxk51Mjgbib2JRzi2cf38t+PHqdeg3Bq149hx554WsaVTVVlZtk5d95RbnmfLMtM+fAn3njOr/Qm5rBBCq++l8qShVu5/4GeV43b6ZRZungHG9bswOFw0LZjHHfe3QVPT0NpH9lZhXj7mNDpyv8aqVQquvdsSveeTSv0Ht0Ig0HHs5OGM278wJL5/SDvcp+l9Wv2cPcdnqVJHaBLB19mzEsh8eAZmsXVvFyzwi1O/Lm+CbjiiUhvHxNxLRoybXY6slyyb+m5s7ks+b2QO+8o2S6uQV0Tk8YHsujnteWutdkcFBVZLmnTy9vE4BGtSMiLp9BWiKzIpOanclGXwsgHOlcorh3bj5GTmcOKRQ4y9kaRfyCG335UKM4rZPXK+HLnzvh6KRMf92bU3SE0j/Xi4ftDGDfag+9nrABgyPDOLFvrYPb8dM6dt7J7Xz4TX0tl0LDueHmVjeTPnc1CcRTSrlXZCF6SJIYN8GHXtoQKxf3eWz+yZ/PvjB8t8+ITWrLPbuH5p7/BZnOwYtle+nd7l6G9PqJPh7f46tMVOJ3XN73kKiaTnpAQ30s+SzabHYPh0s+X0SBht11aU0eoHsSIvRp5ZtII3nzle4Y9kEx0pI7V61IZOyqMgbeVjWbr1zVx4fxZoGTN9VdTfmXr5v0oikztOhE8/vTwcitenp40EF8/D+bP3kJBlplGTSL47IUHqVuvYoWzjh1N5UKKzO0RzdH8b1ONUCWA9ed3krD/FPeO6gaUjICPHEmhx4flqz326ubHp9+eACAszI9Pv3qKubNWs2hSEr5+XgwYOoTbB5TftF2n12C2yMgyqP/2wGdhkROd/uorhE4cT+PwgUQWz4pBpytJio0bmhj//Fm+/foPFs3cQ2NjHL75i86iAAAgAElEQVS+vpjtZn6deQCAJ565+Wrkt+sYyy+Lj9G3h39pxcukk8WcSpFpEuvaOX/h5uGWxG6VNRy3VuyrvHANTPDYx29y9mQqmelZHEqeRfuOJuySDkoG8WzZk09wrdokWYL56MX3aRKZysK5dfAwqVm7IYvnJk7n5W/exT/Yr7TZLg/eS+cHRiLLMur/Zcrj1oqFlGH3Qm/xR0KNwv/mmCUJQ3EwOTaP0s+BoijoPLxITpOJCC+bA08+b8Pg61f2eQkOYfjzjRn+tz5O/P/d9PxC8Imoww9Lsrh7eMl1xcVOpv9YSIsBw6762dt4IImWLTxRtHqsStnxtm08+PjLvUSpGmLQBWKRQVJ7UdujBfN+2Eb3Mfeh1VVt6YKriezcC3ndUe6bcJjbuhvIypFZvsbCXU+O46wUCRX8OQq3Frckdke+iuyVxqufKFwXT+riSV16t4BXX/+SiY/JNKjrSfzBPKZMy2P4gMdJ+O4ieaeTefLFWqhkCaUQerYOJnF/Kis/3M7tPYa5JBb/nDrIGhVnUmwE+GmQVJCb68SiOIjWNin3OWhZux8ffbSCN56LxNNDQ36BnY8/yaBlzIhr/rwMbfsM3817h5UrUoiO0LAr3ky9Wt1opHQne+U/T31pToZy4ogTR175804clSnOcmDU+5b7Ny0eOIolzv3ixMf75tuF6e52kzh8/CC7tydg0HsydlhHgiwhZK90d2RCZRFTMZWk2FzM76uXsHPPVhQFWrdsx6DbhmMyelRZDC2atkOnNfDtnMVkZp8nNDiGEYPGU7dmA+ITd1O3lh6VqvxKjYZ1dSw/fd5lMTRp0AxToImCXBtKth5JArPKjuIn06Z5h3Ln9u02lF9W5jPsoY2Eh+lITbMT17gP3Trcfs39BvgF8p9xn5B06gj5Bbk8MrI2wYGhFbq2fp3GLFvjzfxf0hg+IAS1WmLzjmw2bHFQr05DMk+k46Epu4GbZ8vBYDLg5elDbl4OKedP4+vtR2SNmJui7o9KpaJJ/WY0qd/s6icL1YKkKMrVz3KxurUaKFPe+q7K+60qsizzwZQ3KDpbTJShLhISKZYT6MLUvPTs26jV7v97ejHzAtN//A9LZtYunUcGePuTs6ik4fToeJvL+kpNS+Hb7z8nPysflaRCY9Lw8KjHqV/70o2oAQoK88nKySQoIBgPU9XXpbc77MQn7mb91sVYLGlotSpsVj252RLFRUUUFORTz9iUCN+aFNjzSJGTuOueUWRkpbD/0B80bWQg5ZwdlRTO6BGT8PHyrfLXIFRP/e/vtFdRlFZXO8/9GaYaOnoikazUTOI8OpaO2Op7NCMhfTuJRxNo1rilmyOE4MBQaka254V3djN2VBDeXhpWrMli1z49Tz9SsRUvFRUeFsWbL3zI+QtnccpOwsOiUKuuXMbWy9MbL0/3TGkkHt3Pd3OnorVrkRUFRe9N2zYd2bJxE/V1cfj6+nNBd5aEvJ1kWFKpGVOHMb2foNhcREb2ahbMqIm3pwZFUfhu3nkWLpvKmJEvuuW1CP9eIrFXgtQL5/CQfct9DZckCU+nD+fTz7o0sVusFo6dPIwsO6lfuzEmY8Xrwtw16FHWb43ipf+uxmqzULdmKx4bfWelTBdJkkR42M29CiMnL5tpM7+gvioOX0PJI/kZljR+XbaQFr4d8dX5Awqhpkg8td4cVx/gP+NfRaVSMXXOa4wb7Y+3Z8mvlCRJjBoRxqLlieQX5OHt5fMPPQuCa4nEXgmCAoIxqy+tz2JWFxLo77rVQIeTDjBt1hcYHB5ISBSp8hk18hFaNWtXoevVag29uwykd5eBLovpVrZn/3Z8nYGlSR0gyBCGwe5JTmEW9mwZWZbR6XT4+vhRaC3E7rCj1+mx2orx9S7/66TVSpiMaixWs0jsQpUSDyhVgib149D7ajhZdASHbMchOzhddBTJG+JcNFovNhfx7XefU1eJpamxDU2MrWmkasXsH6aRnZvpkj4up6AoH4vFtVUKbxbF5iI08qXLFXWSnsyiixgx4aX2QWVXk5xxEg+TBzptyRO5taNb8fvanHLXxR/MR5a9CfQPrpL4BeEvLhmxS5J0GzAFUAMzFEV53xXt3qo0Gg0Tx7/KT0tmsyNxHQBNGjXjsaFPotW6prxswqG9eDp98TWVjS69tD742YLYe2Anvbv0d0k/f0k+e4rfVk8jOzcFpyxRJ6YlQ28f47a58MrQoG4TNq5dj1NxopZK7gFYHVay5YtoVTqylIv44E8heaQoSdTzr1863da9Q3++nr2TV98/Q5f2Js6ctbFkhYVh/Z4Te60KVe6GE7skSWrgK6A3cA7YLUnSb4qiHL7Rtm8WTtlJ4pH9HD91FF8fP1rHtcfH2+8fr/H18WPcg0/jcDhQUNBqXPvgitVuRaVcegNSJauxWl371EluXg5zFr7Nc+O96NahHharzOyfjzLr5/eZ8NB/Xb6kz2Ixk5F9ET8ffzw9rq+E8fWoV6shDWMbkZCwnRApAllxkupMxmTyoLl3B07kHeas7TgmjSd1PBoh28uqRXp6ePHkQ++yI/5Plq44jLdnMI/e16PCSywFwZVcMWJvA5xQFOUUgCRJPwGDgWqR2O12G1OmfcCF0xfwcQZgU1lZvuIXnnh0InVrNrjq9RpN5dzGaFS3KYul+dicVnTqko0WHLKdHHUGTRq4dr3yzvhN9OmuoUenkm8HJqOacaNrsGXnaU6nnKBWdF2X9KMoCr+vWcKqtb+jx4BFMdOuTSfuHjL6ht7HtIup5BfkER4a+Y9/KCRJYsx944mP282efTtQq9X0juvL93On4qHxom1wt9Jzk4uOER4VXe56g8FIt/Z9gD6XtG132ElJTUar0dw069uF6ssVWSccOPu3/z4HXFIXVpKkscBYgKCAW6ecwJ871pN5Kos4U4fSX8YMSxqzfviGd17+xG1fs4MDQ+nTuz9r1/xBkFwDCYkM6TxtO3QgOsK1Gzrk5l+gVfPyU0iSJFG7po7svCxq4ZrEvmXXBtb/sZY4Y0cMaiN22cbB7fEYDQsYNnDkNbdXUJTPt7OmkJJ8BqPKRLFSSN/eA+jfe8gVE6tKpaJlbFtaxpZ9hFN7pLBx9Tpq6xrhofEi3ZzKRU0qD/UYW6E4Dh6J55eVX1EjVKbY7MRq9WPk0ImEh0Ze82sShIpwRWK/3G/IJU89KYoyDZgGJQ8ouaDfKrFn305C1VHlEkGgPpTkvGOkZ6QRFuKeLeIABvYdRqP6Tdkdvx1ZdjKs2XDq127s8tFgjZA67NizmwG9y47ZbDLxB808dJfrljCuXb+SmtoGGNQl5QO0Kh31jE3ZtHUdd/Qbcc0Pds3+cRoFp4pp49EdSZKwOi2sXbWKGmERtGjapsLtDOgzFG9vH9auX0lefg516jXg2f4vVehnn5l9kSUrP+WTt0JoVM8TRVFYuymTKdPf5fknvqi0b3TCv5srPlXngL8PPSIA1z2T7mZqtQZZubS8qUxZQSx3qh1Tj9ox9a5+4lVYrBYOJx3AbrfRoG6Tck9Lto7rxJQZy/h8+lkG3RZAYZGTGfMyiIloT2hwxao8VkR+QR5RmvLTW3qVEbvZjt1uv6bEnleQy9Fjh2jj0aP0D51ebSBSVZuNm9dcU2JXqVR069Cbbh16X/3k/2f3/i0M7KOnUb2SJ2glSaJ3tyCW/nGGoycSadLg6nXx/0mxuWR7xas9e+BwODhy/CD5hfnUiqrj1gGJUPlckdh3A3UlSaoJpAJ3A9f+vfkm1bFDVxae/pFAOQS1quTtSjUnExQafEtNKf2TYycPM3/ph8Q2UmMywmfTrXRtfy/d2peUFTDoDTw++m3WbP6Fp17eiV5noFmju+na4dK55BtRr05D0g+lEu1Rp/RYpvUCoSFh6PXXtuuR2VyMVtKWrm75i0FtJKsw2yXxVigOSz4hQZcOAEKCVBQWX/9etBlZ6SxZOY3UtCMA1Aitz9DbH73szdr0jDRm/vRfIsOLiQhT8/1CM7UiO3PnwEfEip1q6oYTu6IoDkmSxgOrKFnuOFNRlEM3HNlNok1cB5KOH2b37k34EoBVsqDyUnhq1AvV4gaY1WZl/tKPmPyaP80alyxdzMiy8fDTP1ArqgFR4TFAyWP+Q/uNBkZXWiyD+g3nw+Nv4Syy46cNIt+eywXVGcYNefqa3+ugwBC0Ji051kz8dGX16C/YztGiSXNXh35FtaObsnrjRob2V0oLruUXOtix18Jjo+pfV5t2u43p895i1AiZO24vub+xbHU60+e9wX8em4Jepy89V1EUfvrtcx6+V2HwbSU3ey1WJ0+9vI1d+xvTrkWnG3yFws3IJRN8iqKsAFa4oq2bjUqlYtRdY+nVrR+nzhzHy9OHxvVib7m50cNJB1m2YjGpF84SEhjGgNuH0KxxS44cP0jj+lJpUgcICtAxtL+J+MRtpYm9KoSHRvLSxLdZs3EFyWdOERpSg/u6309U+LVv36ZWqRk54kFmfj+V4MIITGpPsuR08HfQq2vVbYjRpGEcO+Lr8uxrxxnS3xuzWeaHRfnENbqdQP+g62oz4fBe6tW2cOegsvsbQ/uHsGNvCgmH9tCmecfS4xlZ6ZjNZxnYp+xbkEGvZtQIX2b8sE4k9mrq1spOblQjJIIaIRHuDuO6HE46yDfTPiNaqk9zfSfyLmbz3cypjBo1BlAwGi8dDRsNEk7n/9/B4vooisLx00dJSNyHRqOhdfP2RFyhbkxwYCj3Dn/IJf3GNW7Fc8+8xuat68jKzqRr/W50atu9Sksnq1VqHrp7Ervit/LDwu1o1Ho6t+1G0wbX/60hOzeLurUu/ZnVqy2Rcrb8U8dOpxOdTsX//8Kj16txuOjnK9x8RGKvBIVFBRw5nghA4/qxVZpILufX3xcSIzUgxFhywyzIEIbaqmHpsgU8//QbLFtrJS3dQlhIyTy2xepk2WozPTqWVActNheza99WzqWeoUZYBG1bdqpwOV1FUZi/ZBa7tu8gQA5FQWbD+tXcMfhOenR2XWngK4msEc29d7rmD8X10mq0dGzdjY6tu7mkvcgaMWzeYWfs/WXTO7KssH23g/YtY8qdGxIUhs3mza74PNq28C09d/HyHOrX7uWSeISbj0jsLrZ7/1aWr/2G1s31KDIsX2vjjtvG07xJxVdhuFrq+bO01ncrd8xPF0hi5i6MBhN9ujzAI8/O4o7bTXiYJJavMRPo14EGdRqTlZPJ5ClvoCnU46n4clQ6yso1v/Hck69V6KnKk2eS2LV9B80NHdGoSp6+DXfGsOTXBbSIbYuvzz8/wStcqn7tRmzYVos3P0pm5LBAJCTm/5KJxRpFw7pNy52rUqkY1n88r09+n15dCogK17B+i4WiohjGjOzpplcgVDaR2F0oOzeTFeu/YfrH4URHlqzFPplcxOPPf0nt6C/cVuEvKDCY3OxsAvVlq3jy7bn4+vihVqvp2LontaIasPfAVgoKc1FRwJEjp/gk9V0stmI88v2o7dmw9NrkoiQWLP2B0XeP5deVC9m3fxdqtZr2bTvTr9cQDH9bwXLg0D785ZCSpK4oFJmLMFvMqJ1aNu9cy6A+d1bpe+F0OnA4neVuMP4TWZa5kHEeCYnQ4Bo3xQ1zlUrFw/e8wLoty3npnU0oKDSudztjRg687CqXujUb8PSYT9m1fxt79mcR27AhsQ2b3xQbvgiVQ/xkXSg+cTe9u+pLkzpA7RgPOrfTkXB4D53bumeE1P+2Icyd8x0aSYOP1p8CRx5JtgMMHTyiNFGFhYTTpV1f/vvxKxjyPQnRRWHOLuZIxmFqeZdfvRFhrMW2Q6uY/PmbqDK1NDS0QrY72bNuD6fPnOLZx14qbVer1SLjRFEULmZewG61o0GLRTbz67JFBPgF07F110p/DyxWC8tWzyXhyGZk2U6NkNoM6PUQMZG1r3hN8tmTzJj9FYV5hSiKgo+/N2NGj7+um7muptfp6ddjGP0quDetj7efywvDCTcvsYjVhRwOB8bLLLc2GSXsDsel/1BFWjVrxz0jR3POdIItRX9wSnuIIcOH07ldj3Lnbdy6Bn2BiXqeTfHR+RNqjKCeqhmnC5Kwy/bS85yKA7vThj3bQT3PWEwaDzy13jTyaMG5UymcOnO8rO+49mSpLpBVmIHdasek8sSKGavKTEuPzvy8aE6VlAGet2QKgQE7WPxdNGsXNuDBe/KZvfBtsnIuX+K42FzE599Mxj8vjFaGrrQ2dsM7J5gpUz/AYrVUeryCcCPEiN2FmtRvxtwlP3PfnY7SnXRycu2s+9PM2Hvdu5Fwu5adaNuiI3a7Da1Wd9kphaTjRwhQl3/oyt8rEHWehgJ7Lv76IBRF4ZT5CDVCIzBklC/ZK0kSXvhxPv1s6dOwYcHhjBh+H9NmfoGn7ItKUVEk5RMX2A4fnT9GiyenUk7QqF75uWFXunDxPBnZB/nmw9poNCVjmV5dAjl+ysq23WsY2OceALJyMlm/+Q9OJZ/E4bSiLTIQ4l32hGaYMZLs4nT2H9ojlgkKNzWR2F0oPCyKpvUH8NBTvzP4NiNOJ/z6h5nWzYZWevnWgsJ8Tp5JwqA3ULdmg8vOn0qShO5vc8snk5NYueZXzqelEh4eiVqroshZQCBlsXp5eeMstnPUFo+/HEShkk9E7UjimrVi3dI15dpXFIUi8i/ZJapzux4cPX6IYzuPEWqIIMgQhkalRVEU7IoVo8FIZcrMvkjtGENpUv9Lw3oGDhxOBUqezvzgszfwMQfipw3iRMEhKJaw6M0Y9GXxaZ16CgrzKjVeQbhRIrG7WP9ed9OoXisOHNkJSNw1qJ3Lqy3+f2s3r2TpsgV444cdG2pPiQljn/vHPUaPHE/k628/JUKpRbSuATmHMzkjJ+GUHfjYAvDV+eOQHZwwH6JNmw4M7jectPRUQoLCiI6ohcVqZtWaZSQXJhFpqo2sOEk2J+Eb6kP92o0u6a975z4cTEjATx9YujrmvPkMJj9Tpb8/YSERLFlpxmxxYjSUPd6/O95MSGDJgzu/rVyEvyWUmp5l9xPii7eTmZ1RuubeqTjJV2dRO/rGa/MIQmUSib0S1IyqQ82oOlc/0QVOJiex7LfFNNd3xKAu2cg6rSCFL6d/zH9f+fSKtUAW/zqfWlJDgk0lRbw8td5ozVoyvc6T7DiC3WzDoTiIjW3OfSPGYDKayt00NBpM/GfCq8xfPJvtx1YjSSqaN2vF3UNHX7bPOjH1GTx4OEt/W4AnPtixovfVMf6Ryt9hKMAvkPq1u/Dif7cxbnQw/r5aVm3IYsNWFU+PKbnPsD9xL0aLF/st2wkyhhFqiMDX6M/R4ng0xSokSeK88wwNYhtX2c9WEK6XSOy3uO27NhOsRJQmdYAwUxQXClI4lXKcOjGX1iNRFIWzqcl0+tsSRoAgfRgn8hJ5/fn3WbdlFVazhdimLUr39fz/ggNDeerR57E77Kgk6arL53p2vo22LTpyPPkYilOmcf3Yay7udb2GDxjDhq01ePGd1Vis2dSJacFjo+7Ey9ObjVvXkJeVi8nph0EycKo4iXP6ZJr4tWK7Zg1ytBWVpGJIm+G0a9X5pljyKAj/RCT2W1yx2YxGujTxatBivcLqDUmS8PH2pdCWj7e2rDxvgSMfvc7Aux+9hr8zBJ1i4Ej8D2yMWcNTjz5/xf1ar2Xbv8Sj+1n863wsxRYktUSXjj0Y0v+uSl1TnZaeym8rF5F0/Aje3j706j6MDq27IkkSRcWFLF76I629umLJt2KUTARRg8PWPSTkb6dvzwHcPbTyCp8JQmUQyx1vcXHNWpKpnEdRyvYuKXIUUKwq+Mct6/r0HMBx60GKHSX1vIsdhZywJVJkLqS+Ko66Hk2I9qxDM2N7Mk5lsnX3phuONfFYAvN/nENNWyPamXrRTNOBXRt38svvP99w21eSkZXO5Clvknkwl4a0wj87jMU//cTva5YAJU/Gekq+BHqH4OntRbFSiFkpwlPxRe+nY9jAe1wekyzLHE46yNKVP7N280py83Jc3ofw7yZG7Le4lk3bsL3eZvYnbSOQUGyKjUzVee66azRGg+mK1/Xo1Ber1cLqdb9DMUhaidYd27Fv+x58dQGl50mSRKg6kvj9u69ro4m/W7VmGVGqOvjo/IGS2uj1jc3YvHUdg24bXm7Fjqus3bQSP0swMZ4lf+SMahMmjRer1v5Ozy63Y9AbsSslxbB8vf3w9vTB4bBjsRRSr0XzK35LuV5Op4Nvv5/CiSPH8XUGYVfZWPb7Ih575Bka1Gni0r6Efy+R2G9xarWG8WP+Q8LhfRxMjMdk8qBd6zFE1oj+x+tUKhX9ew+hT/cBFBTm4eXpw8XMC+zesRNFUcrNI9sVO576S5NusbmIDVtWE5+wB6PRRNdOPWgZ2+6Kc9CZWRnU1JRfMWNQG8FasumEfyUk9tOnT+KvDb6kT73dQEbWRerE1EfrpeF8QQo1jFGoVCocKjtZmjQ6tHF98bBd8ds4feg0zT06oZJKvjBnWzP4bs5U3n99yr/2MX9FUTiRfIzzF84RFBBCgzqNxSYgN+Df+SmqZtRqDS2atrlkuzezpZgTp4+h1WqpE9MAjUaDzWal2FyMt5cPKpUKrUaLv2/JRhQ1QiLwC/In9WIyEaaSFTB22UaakswD7cpv3GyxWvjw87ewpTsJ1UZik63MOzWbM92TGTbg8tMXtWrW4WLCBTy0XqXH8u256Iw6fLx9L3sNQPLZU+xP3INaraJF0zaEh0WhKAqHkg6wY9ef2Gx2WrVoQ8vYtpckxtDQMC6cz8BPX7bZhkO2Y5Et+Pn4o1KpGD/2P3w57SPSC1LQSDqy7RcJD4vkp8VzaVCvId069Sm3VeCN2L13B6HqyNKkDuCvDyLZfIyU1OR/5Yobi9XCzJ8+QFFO0bKZju177azaGMyYka/g5el99QaES4jEXg3Jssyvfyxg2R9L8FL7olVrweikbp0GJB46ALKE0cPA8DvupU3zDqXXSZLEow88yeffTiYzPw0dBvKULHr06Etsoxbl+ti1byuWizYae7QqHaEHyMFs2Lianp1vu2zVxn597mDy4TehCIL0oRTY80iRkxgx9H7UqsvvH7t0xc+sX7+GAGcISLBm9UoGDBhKYVEBf67fQAiRqCU1Cw/PZ0+jHYx78JlyI71e3W7no/3vYLJ4EqgPxSpbOG4+SJu27UqTRnhoJP995VNOnklif+IeNm9cjz7dC6PGg70pe9m2809eevYtfLxvvBKlWq3GqpSvg64oCjLOm2IPXXdYvXEJ9Wqf4eWna6JSSSiKwrdzzvPrqlncN+wpd4d3SxKJvZopKMrnw8/f4vSxU/hLwRSSh4feCwoV9pzdTbsaPTBojORZs/nhh5l4eXrTsG7Z3G5ocA3efvljjp04TFFxIbWi6xLgF3hJP0nHj+AnBZWbdtGqdHir/Dhz7hS+Pi0vuSY8NJJJT73G76uXcur0IfxDA3i49+PENmxxybkAZ8+fYf36NbQwdEKrKpnrjnDWYumvPyOj0M6jZ+nxUCWS+CNbOXz8IE3ql5VviAqvybhHnuanxbNJyjiAWqumc9fuDOl/d7m+VCoVNSPr8M13n9FI16p0tVCAPoSk/AOs2bSC4QPvreiP4Yrat+3MD0dmESzXKH1QK92SioePBxFh/zx9Vl0dPLqRqZODS2vLS5LEvcNCGLh0J06n4187PXUjxDtWzSz4ZS7mFCtNpXYY1SYUReGYJYFs5QJNVe1QHApowEfnT4SjNqvXLS+X2KFk15+r1W7x8/MnVb5Q7piiKJjlon8sTxweFsXY0U9W6LUkHtmPvzOoNHlDyfy4h92HYgrLHVdJKvycQRw5llgusQM0qteUN1/4ELPFjE6ru+K2hhnZ6chWBW9j+WmXIF0NDh9JhIEVCvsfNW/SmqMdEtm+bRN+BGFTWbEbrDz14POVMqeceuEsBw7vRa1WE9e4daWXtrgeTtmJRlP+voxWKwEKf1vsJVwDkdirEafTwd79u6irjsWBE4WSm6DBqnCy7Olo1DpkWS4930vrw/msk9fVV6d23dn053r8rUH464OQFZnk4iQCwgL+sRTutVCp1cjSpb/ZigpkxXnJcYdkx2S6/EogSZIwGa+8SgjAw+iJXbHhlB2oVWW/GmZHMT7erqmlL0kSI4c9RPdOfTmRfBST0ZOmDeIqZUXQHxsXE3/wF/r1MuBwwLR5C+jabhSd297Y6iZXa1i3PYuX72D8w5Glx379I4M6Mc1uub2FbxbiXatGbHY7BQV5FFmLQAab04ZeY8CICQc2ipR8QvVhpednWS9Qq+mV17r/k5CgMMY+PIG582dwsugQTsVBzVq1eei+Z1z2ZGbzJq1YtnwJxY5CTJqSrfjy7blY9UUYdQYumM8RaizZhzbPlk22Jp22N1B10dvLhyaNm3E88RB1TU1QS2qKHYWcU07ySLcnXPKa/hIWEk5YSPjVT7xOqWkpxB/8hTlfxuDrUzLlM3yglQeenE2TBi3x8/GvtL6v1W3dRvDN3MOcOnOGNi20HDziICFRy9j7HnR3aLcskdirkeWrF6NyqimU8ghRReKQHVgdZtKls6h1as7rT+Fj88FT602GNY1MfRoP93r0uvtrUr8Z7702hfTMNPQ6A/6+AVe/6BoEB4Zyz4hR/LRwNt62AJAUClQ5PDTqMQL8A5n63WecLziNWtJg19oYc/8TBPoH3VCfo+5+hFnzprLr6HoMKhN2ycrgO4bTpEGci15V1ThwZB/9ehlKkzpAaLCebh0MJB6Nd9umL5fj5enN02PeJ/7QHvYfPEOgfw0mPtoGQyVX/azORGKvJux2G39u3UCrgC7EZ26nWC7ApPIiW75IniaLF599CwmJVWuX83/t3Xl41NW9x/H3dyazZA8JSQhZCIvsZZGwKyAuULWoRatWlFsVatXWe7W116u1i/U+3mpre7u5tD5VK0WEMVAAABLpSURBVHqr1YpLZakstgKCGiAQYkIgEEgIJCEJWSaznPtHIhITSEImmczP7+t58jz8Jr/fbz4zTL5z5vzOnFNcfZARY0Zy84JlpKX0rNVos9mIckdRWX0Mp8NJTHRs5wd1w+xp8/jSmMns+mQHdpuNcaMmnlxI++EHHqektBivz8vQrBHdmtrgdKIio7nj1u9SdfwYtXW1DEoZ3Gapv3Bhs9nw+9t/cvL6INLV/0bfOBxOpk2aBczqdF/VOS3sFtHY1IjxGxKjkpmTtpBDDSU0eOtIllQcLhtDMoYxID6RiePaj1Y5W16flxde/iPbPtxClD2GWu9xRo4czUVzvszYkROC1j8aFxvPzCnnt7vdZrP12rjvxISBJ8f3h6NJ46by9Iq/cPVXPKQmt/Tflxxs5J9bPNy9fHKI06nepoXdImKiY4mOieF4UyUJziQyorLJrdzM0cZyYl1x/OChe5g5/XyuW7y0wzHjPp+P3YU7qD5exZCMYQzJGNppX/nKv7/Mnq355ETOZd+JAsprD1OwuYDivGKikiK567Z7zzgnvOo9qclpzJl+I0u//TwXzHbj9cF7mz1cduFtIVtUXfUdLewWYbPZuPqqr/Pcc0+T4RtBecNBmhuaGWfPIS0pA7FB7qatpKYO4qI5l7Y59ljVUR7/3cN4a/y4A9HUShUjx45m+U3fOW2rOxAIsOFf7zIhcgbV3kpKa0uYZJuNDRvNHg9Sb/j9M7/kJ/c9pl8ND5E5MxYwfvQU8vZsx+Ww8R/LJwftG7Sqf9O/OAvJmTiD2791N87hcNhTwtDo0aQNysAR4SDC5iDbOZr1G9e2O+7ZFU8SXZ3AxMiZjIqewJTIOezP28/691ef9r78fh/NzR7ctkgOndhPGlk4xIkNG4FAgLTITBqON3Dg0L7efMhhp6S0mDfXvMqqdW9Qcay88wN6KDFhIHNmXMh50y7Qov4Foi12ixk9YhzZmcPZU7ib1Oi0NnOSuOxuGhrq2+xfd6KW4n1FzIj6bJSETWxkOobz/uaN7Vr3n3I4nGSmD+FI+SH8xo9dWrp3vMaL2+1GRLATgdfr7YVHGX6MMbzyxgu8t3E9cd4B1PtP8Ne/vcjSJcuYPfWCUMdTFqMtdgtyu9xkZWRzpLG0ze1ljSWMH9922J7f70cQ5HMvBZvY8PvbfwnoVNcuvpESKUDshrLAAZr8DXilmYSERGqaq/E5msnOCs6XlXpbdU0Vr771Ij/71Y959sUnOXBof1DPX1xSyHsb1hPfPJCDtfvwNnjx1xp+/cRjlJQWB/W+lNLCblHXX72UgxFFFNXvoryxlIL67dTGVLJo4eI2+yXEDyBt8GAONx44eZsxhkPN+5maM/OM9zEiexT33fMTJp1/LibBR5FrJ97YRvZ7Csj3f8RNX18WlCGIve1YVQUPP3Y/29/dgetwHKXbynjslw+RV7D9tMc0NNZTXnEYr69rn0hyd27D5XFTVneACbaZjLJNYqJtFun+Yfzm6cfaLJSiVE9pV4xFDc0awQPfe5iNm96lvOwQo4fO4Pzp8zscEXHT9ct5/Lf/TW1DJS5/FLX2KhIzE0/bDXOqtNR0brp2GTdcczN5+bnsLthJTEwM0889r1/OS9KRN1e9Rlz9QIa3rgE70JVKjCeel15+lofu/3nbuel9Xv7y2vNs+uA9HDgxEQEWXbqY+ecvPON92Ox2qjyVDGYoTmkZfigipEg6xVV5HDlaxqCUwb33INUXihZ2C0tOSm0zN7rP52Nr7iZ279lJTEwss6bOIS01nczBQ/jpA79ga+4mqqoryc4axoQxk7s1q57dZmfiuClBHSffV/IL8hjubjsRWpIzhcLqHdSdqG3zZvjqGy+yc9MOcqLm4rA5qffVsfJvr5KQkNhuPvxTTZk4nVdeXYH9lD85v/FjbIZoVwxNp1mfVqmz0aPCLiLXAD8CxgDTjDHbghFKBZ/X5+VXTz7CkeIjJJFKsznAhg1ruemGZeRMmkFUZDRzZ14U6pghERcTR2NFA9ERn31r1muawQauU7512tzs4Z+b1jM58rNphKMjYhniG8nqtW+1KezGGHYVbOe999fh8TRx7qRpnDtlKnu27CHKHw0iBMSHM84JLkOGjvdXQdTTFnse8FXgySBkUb1oy0f/pGLvUSZGzzzZtZDsHcyf/+8ZJo47N+hre4aaMYZPivPZvWcHbnckOZNmkJyU2uG+8+ct4OUVK4j1x+Oyu/EbP0WNeUyfPhvXKbMuNnoawQ8ud9spBqIjYimvKWlz28pVr7B+zVoGkYXD5uStopUMyEpg8Og0DpXuJUkGYRx+Dtv38m/XfVNnMVRB1aNXkzEmHwjabH5W5vP5+NfWdewu3IAxhrEj53Le1Pl99gf9ce42Uuzpbf6v4hwJOBqd7C8t5pyho/skR18IBAL86cUn2PnxdhL9KfhsPt5+53WWLllOzsQZ7fafMeV8jlUeZfXaN3FLNI3+eiZMmMzXrryxzX6x0XFEx8VQ3XiMAc7Pphuo8JRxzphRJ7era6pYs/Ztprjn4LS3vDGkmMFsP7CJr15/LYGAn/yCPOLjEpg941sMTs3opWdCfVH1WTNBRJYDy4HTtpysyhjDc688TkzMLu68pWV5tZdeW8GzL3/Mzdfd2ydvjJGRkdQHqk9u+42f455K6r11YTFypTvyCnLJ+2gHk6POOzm+vs6bxfMr/sD40ZPaTeolInxlwWIunLOQI0fLSIhP7HBaW5vNxjVX3sCzzz9NuncosY4EKr1HqHKWc8uCZSf3Ky4pJN6WeLKof3ofiaRSuDefm65dzuxp83rnwStFF4Y7ishaEcnr4OeK7tyRMeYpY0yOMSbnTAsXW1HR/gIaGnfy6INDmDY5gWmTE/jZg0No8uymcN+ePskwa/pcyjmAx99EWcNB1h16g+0VWzhRd4I/Pv87Dh8p7fwkYeLj3K0kk36yqEPLoiKRJobC4vzTHhcVGc3QrBFnnKt8ysTp3Hn7PUSPcVGRUEL29Czuu+cnbWbJjI6KwWPaXwxtpolYnadF9YFOW+zGmC/mFbUg2negiDkzXUREfPY+GhFhY85MB/sOFDFy2JhezzB25Je4ZOFlrHz7FWqqaxgpE4h2xJE8MJVj1WX87xP/w8MPPG6J9SUjIhwdrrAUMP6gPL6Rw8ac8f/snGGjccY5KK3ZR3pkNiJCTXMVlbZyZk29s8f3r1Rn9AtKfSAuNoGS0kC720tKDXExfdeCu/TiK5k/7xKGxo4kK2UY6WmZOB1OBkcOwX/CULB3d59l6U3TpsyiQg7R7PecvO2Y5wh+l5dzhvX+tQS7zc53vnkvTcm1bGvcQG7Tvyiy7+QbS28jNTmt8xMo1UM9He54FfBrIBl4S0RyjTELgpLMQiaNy+Fnv3uWNRuOceH5SYjAP96r5KPtwr23T+3x+Y0x5O7axroNqzlxoo7x4ydy8dzLiI2Ja7evt9lHjCMOt6vt6jRO3NR/bh6Z/srr82Kz2TqcfhhaWswXL1jIO6veZIAk4xMvTY567rj1nj67njAoZTAP3vsIh8sP4mn2kJmebblrGar/6umomNeA14KUxbLcLjc3X/cDnnzuV/z2mZbFoyMiUvjGdd8NyvJf77y7ktVvv02GbThJ9nRy/5HLto+28F93P9RuRaOxo7/Ex5s/JMuMOHnRtjngocZUMjx7ZI+z9KZD5Qd56a/PUri3ALvdxvSc2Vy9aEmHi1RffsliZuTMoWDvLlwuN+NHtb9o2ttEROejVyER/h2qYSIjLYu7lz/G0cojQMvIoGCMhmlorOftVa8zyT0bt73lTSLBmUT+8Y95b8s6vjx/UZv9J4ydzPoRa9heuJlB9gx8AR9llHDxxZcGfc3SYKqtq+Hnv/4pKZ5MZkdfgi/go3BLPr8/9gvuvv3+Dp/LgYnJDEyc1/dhlQox7WPvQyJCysBBpAwcFLQhjqVlB4gi5mRR/1SSLZWCgl3t9rfbI7hz2fe48rrFOEcIAybEcuuy21m04Oqg5Okt72/dQHRTAplRw7CJHafdxajoiRzcd4CDh/eHOp5S/Yq22MNcfGwCjYF6AibQZu71hsAJMhM7XqjaEeFg9rR5YTWWury8jBjaXjMQEWJs8VRUHiErfWiIkinV/2hhD3OpyWkMHTacor27GB41FrvYOd5cSbkc5MbzloY6XrcZY9ia+z7/WL+KmprjjB41lssuuYqsrGwKPywEPivgAeOnNlBNempm6AIr1Q9pV4wFLFv6bVLGJPFB47tsa1zPfucebl56W1i2Yt95dyUvPv8ckWXxDPOM4+DWQzzy+A8ZNXwM/rhm9p7YTZO/gTpvDXn12xg7fjxpqR1/MlHqi0pb7BYQEx3LHbd+l9q6Ghoa60kemHraoYD9WVNTY8uF4MhZuO0tI12GOcZQeCLA+1s3cu9dD/L626+wI+8DnC4X510wj4WfuzislNLCbilxsfEdLqQRLioqy3HhPlnUP5XkSKGo6BOuWbSEb3z9thClUyp8aFeM6jfi4wbQFGjEF/C1ub3OX0NKyhdr4jilekILu+o34mMTmDwph4KGXJoDHowxVHkqKJcSLpx75qXnlFKf0a4Y1a8s+dqtvOz6M5s/2IgEhNiEOG5ZfAfZmcNDHU2psKGFXfUrLqeLJdfcwjVXLKGpqYHYmHhsNv1gqVR3aGFX/ZLL6WqzLJ1Squu0KaSUUhajhV0ppSxGC7tSSlmMFnallLIYLexKKWUxWtiVUspitLArpZTFaGFXSimL0cKulFIWo4VdKaUsRgu7UkpZjBZ2pZSyGC3sSillMVrYlVLKYrSwK6WUxWhhV0opi9HCrpRSFqOFXSmlLEYLu1JKWYwWdqWUspgeFXYReVRE9ojIDhF5TUQSghVMKaXU2elpi30NMN4YMwH4BLiv55GUUkr1RI8KuzFmtTHG17q5GcjoeSSllFI9Ecw+9puBvwfxfEoppc5CRGc7iMhaYFAHv7rfGPN66z73Az7ghTOcZzmwHCA5KfWswiqllOpcp4XdGHPRmX4vIkuBy4ELjTHmDOd5CngK4Jxho0+7n1JKqZ7ptLCfiYgsBL4PzDXGNAQnklJKqZ7oaR/7b4BYYI2I5IrIE0HIpJRSqgd61GI3xowIVhCllFLBod88VUopi9HCrpRSFqOFXSmlLEYLu1JKWYwWdqWUshgt7EopZTFa2JVSymLkDLMA9N6dihwFSlo3BwLH+jxEcGj2vheuuUGzh0q4Zu8o9xBjTHJnB4aksLcJILLNGJMT0hBnSbP3vXDNDZo9VMI1e09ya1eMUkpZjBZ2pZSymP5Q2J8KdYAe0Ox9L1xzg2YPlXDNfta5Q97HrpRSKrj6Q4tdKaVUEPWLwi4iD4nIjtY53VeLyOBQZ+oqEXlURPa05n9NRBJCnakrROQaEdklIgERCYsRAyKyUEQKRKRIRP4z1Hm6SkSeEZEKEckLdZbuEJFMEVknIvmtr5W7Qp2pq0TELSIfiMj21uw/DnWm7hIRu4h8LCJvdvfYflHYgUeNMROMMZOAN4EHQx2oG9YA440xE4BPgPtCnKer8oCvAhtDHaQrRMQO/Bb4MjAWuF5ExoY2VZf9CVgY6hBnwQfcY4wZA8wA7gij59wDzDfGTAQmAQtFZEaIM3XXXUD+2RzYLwq7Mab2lM1oIGw6/o0xq40xvtbNzUBGKPN0lTEm3xhTEOoc3TANKDLGFBtjmoGXgCtCnKlLjDEbgapQ5+guY0yZMeaj1n/X0VJk0kObqmtMixOtm47Wn7CpKyKSAVwG/OFsju8XhR1ARB4WkYPADYRXi/1UNwN/D3UIi0oHDp6yXUqYFBkrEJFsYDKwJbRJuq61KyMXqADWGGPCJjvwS+BeIHA2B/dZYReRtSKS18HPFQDGmPuNMZnAC8CdfZWrKzrL3rrP/bR8dH0hdEnb6kruMCId3BY2LbBwJiIxwF+Bf//cp+t+zRjjb+3ezQCmicj4UGfqChG5HKgwxnx4tufo0Zqn3WGMuaiLu64A3gJ+2ItxuqWz7CKyFLgcuND0o/Gj3XjOw0EpkHnKdgZwOERZvjBExEFLUX/BGPNqqPOcDWPMcRFZT8t1jnC4gD0bWCQilwJuIE5E/myMWdLVE/SLrhgROeeUzUXAnlBl6S4RWQh8H1hkjGkIdR4L2wqcIyJDRcQJXAesDHEmSxMRAf4I5BtjfhHqPN0hIsmfjlATkUjgIsKkrhhj7jPGZBhjsml5nb/bnaIO/aSwA4+0dhHsAC6h5WpwuPgNEAusaR2u+USoA3WFiFwlIqXATOAtEVkV6kxn0nqB+k5gFS0X8f5ijNkV2lRdIyIvApuAUSJSKiK3hDpTF80GbgTmt762c1tbkeEgDVjXWlO20tLH3u1hg+FKv3mqlFIW019a7EoppYJEC7tSSlmMFnallLIYLexKKWUxWtiVUspitLArpZTFaGFXSimL0cKulFIW8/9Q0ZR1Mhxv5wAAAABJRU5ErkJggg==\n",
      "text/plain": [
       "<Figure size 432x288 with 1 Axes>"
      ]
     },
     "metadata": {},
     "output_type": "display_data"
    }
   ],
   "source": [
    "tree = DecisionTreeClassifier(max_bins=15,min_samples_leaf=3)\n",
    "tree.fit(data, target)\n",
    "utils.plot_decision_function(data, target, tree)"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "### 决策树另外一种理解：条件概率分布\n",
    "决策树还可以看作是给定特征条件下类的条件概率分布：  \n",
    "\n",
    "（1）训练时，决策树会将特征空间划分为大大小小互不相交的区域，而每个区域对应了一个类的概率分布；  \n",
    "\n",
    "（2）预测时，落到某区域的样本点的类标签即是该区域对应概率最大的那个类"
   ]
  }
 ],
 "metadata": {
  "kernelspec": {
   "display_name": "Python 3",
   "language": "python",
   "name": "python3"
  },
  "language_info": {
   "codemirror_mode": {
    "name": "ipython",
    "version": 3
   },
   "file_extension": ".py",
   "mimetype": "text/x-python",
   "name": "python",
   "nbconvert_exporter": "python",
   "pygments_lexer": "ipython3",
   "version": "3.6.4"
  }
 },
 "nbformat": 4,
 "nbformat_minor": 2
}
